/*
* @(#)LotusDominoMailer.java
*
* Copyright (c) 2003 DCIVision Ltd
* All rights reserved.
*
* This software is the confidential and proprietary information of DCIVision
* Ltd ("Confidential Information").  You shall not disclose such Confidential
* Information and shall use it only in accordance with the terms of the license
* agreement you entered into with DCIVision Ltd.
 */
package com.dcivision.framework.notification;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.net.URLConnection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.Vector;

import lotus.domino.Database;
import lotus.domino.Document;
import lotus.domino.EmbeddedObject;
import lotus.domino.NotesFactory;
import lotus.domino.RichTextItem;
import lotus.domino.Session;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.dcivision.framework.ApplicationException;
import com.dcivision.framework.SystemParameterConstant;
import com.dcivision.framework.SystemParameterFactory;
import com.dcivision.framework.TextUtility;
import com.dcivision.framework.Utility;
import com.dcivision.framework.bean.GenericAddress;

/**
 * <p>Class Name:       LotusDominoMailer.java    </p>
 * <p>Description:      This class send email out through Lotus Notes Domino Server</p>
 *
 * @author           Rollo Chan
 * @company          DCIVision Limited
 * @creation date    01/06/2005
 * @version          $Revision: 1.14 $
 */

public class LotusDominoMailer {
  private String host = "";
  private String user = "";
  private String pwd = "";
  private String iorFilePath = "";
  private String ior = "";
  private String dbFileHost = "";
  private String dbFilePath = "";

  public static final String REVISION = "$Revision: 1.14 $";

  private Log log = LogFactory.getLog(this.getClass().getName());

  private boolean m_bDebug = false;

  public LotusDominoMailer() {
    host = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_HOST);
    user = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_USERNAME);
    pwd = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_PASSWORD);
    iorFilePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_IOR_FILE_PATH);
    dbFileHost = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_DB_FILE_HOST);
    dbFilePath = SystemParameterFactory.getSystemParameter(SystemParameterConstant.DOMINO_DB_FILE_PATH);
  }

  public void setDebug(boolean debug) {
  	m_bDebug = debug;
  }

  public void sendEmail(EmailDeliveryMessage message) throws ApplicationException{
	  List messages = new ArrayList();
	  messages.add(message);
	  sendEmail(messages);
  }

  public void sendEmail(List messages) throws ApplicationException{
    Session session = null;
    Database db = null;
    EmailDeliveryMessage em = null;
    try {
      // Get the connection IOR string.
      if (Utility.isEmpty(iorFilePath)) {
        ior = NotesFactory.getIOR(host);
      } else {
        FileInputStream fin = new FileInputStream(iorFilePath);
        InputStreamReader fisr = new InputStreamReader(fin);
        BufferedReader br = new BufferedReader(fisr);
        ior = br.readLine();
        fin.close();
      }

      // Login to the Lotus Domino server.
      session = NotesFactory.createSessionWithIOR(ior, user, pwd);
      java.util.Vector vecAddressBook = session.getAddressBooks();

      String p = session.getPlatform();
      String nv = session.getNotesVersion();
      String un = session.getUserName();
      log.debug("Number of Accessible Database: " + vecAddressBook.size());
      log.debug("Current Platform: " + p);
      log.debug("Current Domino Version: " + nv);
      log.debug("Current User Name: " + un);

      if (Utility.isEmpty(dbFilePath)) {
        // Use the first accessible database to send mail.
        for (int i = vecAddressBook.size() - 1; i >= 0 ; i--) {
          try {
            db = (Database)vecAddressBook.get(i);
            if (!db.isOpen()) {
              db.open();
            }
            break;
          } catch (Exception ignore) {
          }
        }
      } else {
        // Use user defined database host and file path to send mail.
        db = session.getDatabase(dbFileHost, dbFilePath);
        if (!db.isOpen()) {
          db.open();
        }
      }

      for (int i = 0; i < messages.size(); i++) {
        em = (EmailDeliveryMessage)messages.get(i);

        // Receiptient list construction.
        String subject = em.getSubject();
        String content = em.getMailContent();
			  Vector sendToVec = new Vector();
			  Vector copyToVec = new Vector();
			  Vector blindCopyToVec = new Vector();

        GenericAddress[] sendToAry = em.getToRecipientArray();
        for (int j = 0; j < sendToAry.length; j++) {
          sendToVec.add(sendToAry[j].getAddress());
        }

        GenericAddress[] copyToAry = em.getCCRecipientArray();
        for (int j = 0; j < copyToAry.length; j++) {
          copyToVec.add(copyToAry[j].getAddress());
        }

        GenericAddress[] blindCopyToAry = em.getBCCRecipientArray();
        for (int j = 0; j < blindCopyToAry.length; j++) {
          blindCopyToVec.add(blindCopyToAry[j].getAddress());
        }

        // Create the Lotus mail body.
			  Document memo = db.createDocument();
        RichTextItem body = null;
        File temp[] = null;
        FileOutputStream fos = null;

        try {
  			  // Set the field values
  			  memo.setSaveMessageOnSend(false);
//  			  memo.replaceItemValue("SendTo", sendToVec);
  			  memo.replaceItemValue("CopyTo", copyToVec);
  			  memo.replaceItemValue("BlindCopyTo", blindCopyToVec);
  			  memo.replaceItemValue("Form", "Memo");
  			  memo.replaceItemValue("Subject", subject);
  			  if (em.getSender() != null) {
            memo.replaceItemValue("ReplyTo", em.getSender().getAddress());
          }
  			  body = memo.createRichTextItem("Body");
  			  String contentWithLinkConverted = convertLink(content);
  			  body.appendText(TextUtility.htmlToPlainText(contentWithLinkConverted,true));

  			  // Attachment
  			  Set attachKeySet = em.getAttachmentMap().keySet();
  			  temp = new File[attachKeySet.size()];
  			  int loop = 0;
  			  log.debug("Attachment No.:" + attachKeySet.size());
          for (Iterator iterator = attachKeySet.iterator(); iterator.hasNext();) {
            ByteArrayDataSource bads = null;
            String fileName = (String) iterator.next();
            String fileContentType = URLConnection.guessContentTypeFromName(fileName) != null ? URLConnection.guessContentTypeFromName(fileName) : "application/octet-stream";

            if (em.getAttachmentMap().get(fileName) instanceof byte[]) {
              byte[] data = (byte[]) em.getAttachmentMap().get(fileName);
              bads = new ByteArrayDataSource(data, fileContentType);
            } else {
              java.io.InputStream is = (java.io.InputStream) em.getAttachmentMap().get(fileName);
              bads = new ByteArrayDataSource(is, fileContentType);
            }

            // Write the content to a temporary file.
            java.io.InputStream tmpInput = bads.getInputStream();
            temp[loop] = File.createTempFile(Utility.getCurrentTimestamp().getTime() + fileName, "");
            fos = new FileOutputStream(temp[loop]);
            int inByte = -1;
            while ((inByte = tmpInput.read()) != -1) {
              fos.write(inByte);
            }
            fos.close();

            // Attach the temporary file to the mail.
            log.debug("Attachment Link:" + temp[loop].getAbsolutePath());
            log.debug("Attachment Name:" + fileName);
            body.addNewLine(2);
            body.embedObject(EmbeddedObject.EMBED_ATTACHMENT, null, temp[loop].getAbsolutePath(), fileName);
            loop++;
          }

  			  // Send it off
  			  memo.send(true, sendToVec);
        } catch (Exception e) {
          log.error(e, e);
          throw new ApplicationException(e);
        } finally {
          for (int tmpCnt = 0; tmpCnt < temp.length; tmpCnt++) {
            temp[tmpCnt].delete();
          }
          try { body.recycle(); } catch (Exception ignore) {} finally { body = null; }
          try { memo.recycle(); } catch (Exception ignore) {} finally { memo = null; }
        }
      }
    } catch (Exception e) {
      log.error(e, e);
      throw new ApplicationException(e);
    } finally {
      try { db.recycle(); } catch (Exception ignore) {} finally { db = null; }
      try { session.recycle(); } catch (Exception ignore) {} finally { session = null; }
    }
  }

  private String convertLink(String content) {
    String result = content;
    String linkText = "";
    String linkURL = "";

    int hrefIdx = content.indexOf("href=");
    if (hrefIdx < 0 || content.indexOf("<") < 0 || content.indexOf("'") < 0 || content.indexOf("</a>") < 0 || content.indexOf("<a href") < 0) {
      return content;
    }
    linkText = content.substring(content.indexOf(">", hrefIdx) + 1);
    linkText = linkText.substring(0, linkText.indexOf("<"));

    linkURL = content.substring(hrefIdx + 6);
    linkURL = linkURL.substring(0, linkURL.indexOf("'"));

    result = content.substring(0, content.indexOf("<a href"));
    result += linkText + "<br>" + linkURL;

    result += content.substring(content.indexOf("</a>") + 4);

    return(result);
  }
}